//Direct Input Header File
//Declares the class used for Direct Input
//Jeffrey Denton	January 20, 2011

//Windows Include File

//SDK Include File

//Project Include File
#include "DirectInput.h"

/*******************************************************\
*	Default Destructor									*
\*******************************************************/
DirectInput::~DirectInput()
{
	Shutdown();
}

/*******************************************************\
*	Initialize Direct Input								*
\*******************************************************/
bool DirectInput::Init(HINSTANCE hInstance, HWND hWnd)
{
	DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DIObject, NULL);	//Create DI Object

	//Initialize all keys' history to false
	for(int i = 0; i < 256; ++i)
	{
		KeyPressed[i] = false;
	}

	//Create a Keyboard Device
	DIObject->CreateDevice(GUID_SysKeyboard, &DIKeyboard, NULL);
	DIKeyboard->SetDataFormat(&c_dfDIKeyboard);
	DIKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);	//Keyboard only works in foreground for any application
	hr = DIKeyboard->Acquire();
	//Validate Keyboard was acquired
	if(FAILED(hr)){return false;}	

	//Create a Mouse Device
	DIObject->CreateDevice(GUID_SysMouse, &DIMouse, NULL);
	DIMouse->SetDataFormat(&c_dfDIMouse2);
	DIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);		//Mouse only works in foreground for any application
	hr = DIMouse->Acquire();
	//Validate Mouse was acquired
	if(FAILED(hr)){return false;}

	::ZeroMemory(KeyState, sizeof(KeyState));

	return true;
}

/*******************************************************\
*	Poll Devices										*
\*******************************************************/
void DirectInput::UpdateInput(HWND hWnd)
{
	GetCursorPos(&CursorPosition);
	ScreenToClient(hWnd,&CursorPosition);

	DIKeyboard->GetDeviceState	(sizeof(KeyState),(LPVOID)&KeyState);
	DIMouse->GetDeviceState		(sizeof(MouseState), (void*)&MouseState); 

	HRESULT hr = DIKeyboard->GetDeviceState(sizeof(KeyState), (void*)&KeyState);
	if(FAILED(hr))
	{	
		ZeroMemory(KeyState, sizeof(KeyState));

		hr = DIKeyboard->Acquire();		// attempt to re-acquire the device if unable to GetDeviceState
		hr = DIMouse->Acquire();		//Aquire the mouse
	}
}

/*******************************************************\
*	Test for Keyboard Press	Once						*
\*******************************************************/
bool DirectInput::KeyOnce(unsigned char key)//Return which key has been pressed on the keyboard
{
	if(KeyPressed[key] == false && (KeyState[key] & 0x80) != 0)
	{
		KeyPressed[key] = true;
		return true;
	}
	if(KeyPressed[key] == true && (KeyState[key] & 0x80) == 0)
	{
		KeyPressed[key] = false;
	}
	return false;
}

/*******************************************************\
*	Test for a key being held down						*
\*******************************************************/
bool DirectInput::KeyDown(unsigned char key)//Return which key has been pressed on the keyboard
{
	if((KeyState[key] & 0x80) != 0)
	{
		return true;
	}
	return false;
}

/*******************************************************\
*	Test for Mouse Click								*
\*******************************************************/
bool DirectInput::MouseDown(int button)		//Return which button has been pressed on the mouse
{
	if(MouseState.rgbButtons[button] & 0x80){
		MouseState.rgbButtons[button] = false;
		return true;
	}
	return false;
}

/*******************************************************\
*	Find Mouse Position									*
\*******************************************************/
POINT DirectInput::GetCursor()
{
	return CursorPosition;
};

/*******************************************************\
*	Release all variables								*
\*******************************************************/
bool DirectInput::Shutdown()
{
	if(DIKeyboard)
	{
		DIKeyboard->Unacquire();
		DIKeyboard = 0;
	}
	if(DIMouse)
	{
		DIMouse->Unacquire();
		DIMouse = 0;
	}

	return true;
}